package com.gonsin.gview.logic.controller;

import com.gonsin.base.ResponseResult;
import com.gonsin.gview.annotations.model.*;
import com.gonsin.gview.logic.config.GViewMenuService;
import com.gonsin.gview.logic.model.*;
import com.gonsin.gview.logic.services.GFileServiceImpl;
import com.gonsin.gview.logic.services.GViewActionServiceImpl;
import com.gonsin.gview.logic.services.GViewCoreServiceImpl;
import com.gonsin.gview.logic.services.GViewDataServiceImpl;
import com.gonsin.gview.model.GViewModel;
import com.gonsin.gview.model.menu.GViewMenu;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.ToNumberPolicy;
import com.google.gson.reflect.TypeToken;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.*;

@RestController
@Api(tags = "模板接口")
@RequestMapping("/restapi/s09/gview")
public class GViewController {

    @Autowired private GViewCoreServiceImpl coreService;
    @Autowired private GViewDataServiceImpl dataService;
    @Autowired private GViewActionServiceImpl actionService;
    @Autowired private GFileServiceImpl fileService;
    @Autowired private GViewMenuService menuService;
    @ApiOperation("视图 - 获取一个视图")
    @GetMapping("/views")
    public ResponseResult<GViewModel> getBoard(
            @ApiIgnore HttpServletResponse response,
            @ApiIgnore HttpServletRequest request,
            @ApiParam("页面现存的参数") @RequestParam(value = "props", required = false) String props,
            @ApiParam("页面的名字") @RequestParam("viewName") String viewName){
        ViewRequest viewRequest = new ViewRequest();
        viewRequest.setViewName(viewName);

        if(StringUtils.isEmpty(props)){
            viewRequest.setProps(new HashMap<>());
        } else {
            Gson gson = new GsonBuilder()
                    .setObjectToNumberStrategy(ToNumberPolicy.LONG_OR_DOUBLE)
                    .enableComplexMapKeySerialization()
                    .disableHtmlEscaping().create();
            Type type = new TypeToken<Map<String, Object>>() {
            }.getType();
            Map<String, Object> propsMap = gson.fromJson(props, type);
            viewRequest.setProps(propsMap);
        }
        viewRequest.setRequest(request);
        viewRequest.setResponse(response);
        return ResponseResult.result(coreService.findModelByRequest(viewRequest));
    }

    @ApiOperation("视图 - 获取所有视图")
    @GetMapping("/boards/all")
    public ResponseResult<Set<String>> getBoard(){
        return ResponseResult.result(coreService.findAllBoard());
    }


    @ApiOperation("菜单 - 获取个人菜单")
    @GetMapping("/menus")
    public ResponseResult<List<GViewMenu>> menus(@ApiIgnore HttpServletRequest request){
        return ResponseResult.result(menuService.getMenus(request));
    }

    @ApiOperation("菜单 - 获取内置所有菜单")
    @GetMapping("/menus/inner")
    public ResponseResult<List<GViewMenu>> getMenuViews(HttpServletRequest request, HttpServletResponse response){
        List<GViewMenu> all = coreService.getAllMenus(request, response);
        List<GViewMenu> tree = new ArrayList<>();
        tree.add(new GViewMenu("ALL", "全部菜单（不分级）", null, null, null));
        all.forEach(m -> {
            m.setParent("ALL");
        });
        tree.addAll(all);
        return ResponseResult.result(tree);
    }


    @ApiOperation("数据 - 获取数据")
    @PostMapping("/data")
    public ResponseResult<? extends Object> getData(
            @ApiIgnore HttpServletRequest request,
            @ApiIgnore HttpServletResponse response,
            @RequestBody DataRequest dataRequest) throws Throwable {
        Object data = dataService.getData(request, response, dataRequest);
        return ResponseResult.result(data);
    }

    @ApiOperation("数据 - 获取所有数据关系")
    @PostMapping("/data/all")
    public ResponseResult<List<DataPo>> getAllData(){
        // TODO 此接口标注开发阶段时候才能访问

        List<DataPo> data = dataService.getAllData();
        return ResponseResult.result(data);
    }


    @ApiOperation("触发 - 触发批量操作事件")
    @PostMapping("/active/batch")
    public ResponseResult<Void> activeBatch(
            @ApiIgnore HttpServletRequest request,
            @ApiIgnore HttpServletResponse response, @RequestBody BatchRequest batch) throws Throwable {
        actionService.activeBatch(request, response, batch);
        return ResponseResult.simpleResult();
    }


    @ApiOperation("触发 - 触发下载事件")
    @PostMapping("/active/download")
    public ResponseResult<DownloadResponse> activeDownload(
            @ApiIgnore HttpServletRequest request,
            @ApiIgnore HttpServletResponse response,
            @RequestBody DownloadRequest downloadRequest
            ) throws Throwable {
        ;
        return ResponseResult.result(actionService.activeDownload(request, response, downloadRequest));
//        return ResponseResult.simpleResult();
    }

    @ApiOperation("触发 - 触发confirm事件")
    @PostMapping("/active/confirm")
    public ResponseResult<? extends Object> activeConfirm(
            @ApiIgnore HttpServletResponse response,
            @ApiIgnore HttpServletRequest request, @RequestBody ConfirmRequest confirmRequest) throws Throwable {
        actionService.activeConfirm(request, response, confirmRequest);
        return ResponseResult.simpleResult();
    }

    @ApiOperation("触发 - 触发文件上传事件")
    @PostMapping("/active/file")
    public ResponseResult<? extends Object> activeFile(
            @ApiIgnore HttpServletRequest request,
            @ApiIgnore HttpServletResponse response,
            @RequestBody @Validated FileRequest fileRequest) throws Throwable {
        actionService.activeFile(request, response, fileRequest);
        return ResponseResult.simpleResult();
    }

    @ApiOperation(value = "触发 - 上传文件", notes = "支持多文件上传")
    @PostMapping("/active/upload_file")
    public ResponseResult<List<String>> uploadFile(
            @ApiIgnore HttpServletRequest request,
            @RequestParam("file") MultipartFile[] file) throws IOException {
        if(file == null || file.length == 0){
            return ResponseResult.result(new ArrayList<>());
        }

        List<String> list = new ArrayList<>();
        for(MultipartFile f : file){
            File tempFile = fileService.newTempFile(FilenameUtils.getExtension(f.getOriginalFilename()));
            f.transferTo(tempFile);
            list.add(fileService.getUrlFromPath(tempFile.getAbsolutePath()));
        }

        return ResponseResult.result(list);
    }

}
